package com.bossly.metro.Activities;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.bossly.metro.CoreApplication;
import com.bossly.metro.Metropoliten;
import com.bossly.metro.R;
import com.bossly.metro.Views.CompassView;
import com.bossly.metro.Views.DirectionView;
import com.bossly.metro.Views.MetroView;
import com.bossly.metro.dom.Station;

public class DirectionActivity extends Activity implements OnClickListener,
		LocationListener {
	public final static String STATION_START = "station_start";
	public final static String STATION_FINISH = "station_finish";

	public final static String START_LAT = "station_start_lat";
	public final static String START_LNG = "station_start_lng";

	public final static String FINISH_LAT = "station_finish_lat";
	public final static String FINISH_LNG = "station_finish_lng";

	private int m_startStation = -1;
	private int m_finishStation = -1;

	private static final float MIN_GPS_DISTANCE = 20; // 10 meters
	private static final int DIALOG_GPS = 1;
	private CoreApplication m_app;

	private Location mStartLocation = null;
	private Location mStartMetroLocation = null;
	private Location mFinishLocation = null;

	private TextView txtHelp;
	private Metropoliten metro;
	private CompassView m_compass;
	private LocationManager lm;
	private View mStartPanel;
	private View btnMap;
	private ArrayList<Station> way;
	private View m_btnPlay;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		setContentView(R.layout.way);

		m_app = (CoreApplication) getApplication();
		metro = m_app.getMetropoliten();

		DirectionView wayView = (DirectionView) findViewById(R.id.way);

		btnMap = findViewById(R.id.showonmap);
		btnMap.setOnClickListener(this);
		btnMap.setEnabled(mStartLocation != null);

		m_btnPlay = findViewById(R.id.btn_play);
		m_btnPlay.setOnClickListener(this);

		mStartPanel = findViewById(R.id.startpoint);
		txtHelp = (TextView) findViewById(R.id.txtHelp);
		m_compass = (CompassView) findViewById(R.id.compass);

		final Intent intent = getIntent();

		if (intent != null) {
			m_startStation = intent.getIntExtra(STATION_START, -1);
			m_finishStation = intent.getIntExtra(STATION_FINISH, -1);

			mStartMetroLocation = metro.getStation(m_startStation)
					.getLocation();

			if (intent.hasExtra(START_LAT) && intent.hasExtra(START_LNG)) {
				// mStartLocation = new Location( "custom" );
				// mStartLocation.setLatitude( intent.getDoubleExtra( START_LAT,
				// 0 ) );
				// mStartLocation.setLongitude( intent.getDoubleExtra(
				// START_LNG, 0 ) );
			}

			if (intent.hasExtra(FINISH_LAT) && intent.hasExtra(FINISH_LNG)) {
				mFinishLocation = new Location("custom");
				mFinishLocation.setLatitude(intent
						.getDoubleExtra(FINISH_LAT, 0));
				mFinishLocation.setLongitude(intent.getDoubleExtra(FINISH_LNG,
						0));
			}
		}

		txtHelp.setText(R.string.calculation);

		updateTitle();
		startTracking();

		way = metro.findShortway(m_startStation, m_finishStation);
		wayView.setDirections(way);
	}

	@Override
	protected void onResume() {
		if (mStartMetroLocation != null) {
			m_compass.setEndLocation(mStartMetroLocation);
		}

		// TODO Auto-generated method stub
		super.onResume();
	}

	@Override
	protected void onPause() {
		if (lm != null) {
			lm.removeUpdates(this);
		}

		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.help, menu);
		// getMenuInflater().inflate( R.menu.way_actions, menu );

		// TODO Auto-generated method stub
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dlg;
		Builder builder;

		switch (id) {
		case DIALOG_GPS:
			builder = new Builder(this);
			builder.setTitle(R.string.service_gps);
			builder.setMessage(R.string.gps_body);

			builder.setPositiveButton(R.string.gps_yes,
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							/* bring up the GPS settings */
							Intent intent = new Intent(
									android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							startActivity(intent);
						}
					});

			builder.setNegativeButton(R.string.gps_no, null);

			dlg = builder.create();
			break;

		default:
			dlg = super.onCreateDialog(id);
			break;
		}

		return dlg;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menuPayment:
			startActivity(new Intent(this, PaymentActivity.class));
			break;

		case R.id.menuSms:
			// Intent intent = new Intent(Intent.ACTION_PICK);
			// intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
			// startActivityForResult(intent, PICK_CONTACT);

			// sendSms();
			break;
		}

		// TODO Auto-generated method stub
		return super.onOptionsItemSelected(item);
	}

	private void updateLocation(Location start) {
		mStartLocation = start;
		btnMap.setEnabled(mStartLocation != null);

		// there are x meters to the station
		int m = (int) mStartMetroLocation.distanceTo(start);

		if (m < MIN_GPS_DISTANCE) {
			mStartPanel.setVisibility(View.GONE);
		} else {
			mStartPanel.setVisibility(View.VISIBLE);

			int km = m / 1000;
			m = m - km * 1000;

			if (km > 0)
				txtHelp.setText(String.format(
						getString(R.string.distanse_km_m), km, m));
			else
				txtHelp.setText(String
						.format(getString(R.string.distanse_m), m));

			m_compass.setStartLocation(start);
		}
	}

	private void updateTitle() {
		setTitle(getString(R.string.app_title, m_app.getCityName()));
	}

	final Handler hideButton = new Handler() {
		public void handleMessage(android.os.Message msg) {
			m_btnPlay.setBackgroundResource(R.drawable.button_play_selector);
		};
	};

	@Override
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.btn_play:
			// play animation
			MetroView mView = (MetroView) findViewById(R.id.mapView);

			if (mView.isTutorial()) {
				mView.stopTutorial(way);
			} else {
				m_btnPlay
						.setBackgroundResource(R.drawable.button_stop_selector);

				mView.setMap(m_app.getCity());
				mView.setMetropolite(metro);
				mView.showTutorial(way, hideButton);
			}

			break;

		case R.id.showonmap:
			Location location = metro.getStation(m_startStation).getLocation();
			double lat = location.getLatitude();
			double lng = location.getLongitude();

			// show direction to first station
			if (mStartLocation != null) {
				String sLat = String.valueOf(mStartLocation.getLatitude());
				String sLng = String.valueOf(mStartLocation.getLongitude());
				String endLat = String.valueOf(lat);
				String endLng = String.valueOf(lng);

				String query = "http://maps.google.com/maps?f=d&saddr=" + sLat
						+ "%20" + sLng + "&daddr=" + endLat + "%20" + endLng
						+ "&hl=en";

				// show direction
				Uri uri = Uri.parse(query);
				Intent it = new Intent(Intent.ACTION_VIEW, uri);
				startActivity(it);
				// where startLat, startLng, endLat, endLng are a long with 6
				// decimals
				// like: 50.123456
			}
			break;
		}
	}

	private void startTracking() {
		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
		} else {
			txtHelp.setText(R.string.unknown);
			Toast.makeText(this, R.string.gps_disable, Toast.LENGTH_LONG)
					.show();
			showDialog(DIALOG_GPS);
		}

		if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
			lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
					this);
	}

	@Override
	public void onLocationChanged(Location location) {
		updateLocation(location);
	}

	@Override
	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub

	}

}
